<?php

namespace App\Services\Group;

use App\Constant\GroupEnum;
use App\Constant\GroupMemberEnum;
use App\Models\Group;
use App\Models\GroupMember;
use App\Models\User;
use App\Services\User\UserHashidService;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class GroupService
{
    // 提权为团长，只会执行一次
    public static function make(User $user, array $payload = [])
    {
        $attributes = [
            'user_id' => $user->getAttribute('id'),
        ];
        $group = Group::query()->where($attributes)->first();
        DB::beginTransaction();
        try {
            if (!$group) {
                $attributes = array_merge($attributes, [
                    'created_by' => GroupEnum::CREATED_BY_GRANTED,
                ]);
                $group = Group::query()->create($attributes);
            }
//            if (!empty($payload)) {
//                $mobile = $payload['phone'] ?? '';
//                if (!empty($mobile)) {
//                    $has = User::query()
//                        ->where('phone', $mobile)
//                        ->where('id', '!=', $user->getAttribute('id'))
//                        ->exists();
//                    if ($has) {
//                        throw new \Exception('手机号已存在');
//                    }
//                }
//                $password = Hash::make($payload['password'] ?? '');
//                $user->update([
//                    'phone' => $mobile,
//                    'password' => $password,
//                ]);
//            } else {
//                $pwd = Str::random(5);
//                $crt = [
//                    'phone' => UserHashidService::encode($user->id),
//                    'dip' => $pwd,
//                    'password' => Hash::make($pwd),
//                ];
//                $user->update($crt);
//            }

            $user->update([
                'is_group_leader' => 1,
            ]);

            // 更新下级组员数据，获取所有下级用户及其下级用户
            $children = self::getAllDescendants($user);
            GroupMember::query()
                ->where([
                    'group_id' => $group->id,
                    'leader_id' => $user->getAttribute('id'),
                ])->delete();
            $attributes = [];
            foreach ($children as $child) {
                $member = GroupMember::query()
                    ->where([
                        'user_id' => $child->getAttribute('id'),
                    ])->first();
                if ($member) {
                    $member->update([
                        'group_id' => $group->id,
                        'leader_id' => $user->getAttribute('id'),
                    ]);
                    continue;
                }
                $attributes[] = [
                    'group_id' => $group->id,
                    'leader_id' => $user->getAttribute('id'),
                    'user_id' => $child->getAttribute('id'),
                    'type' => GroupMemberEnum::TYPE_MEMBER,
                    'joined_at' => $child->getAttribute('registered_at'),
                    'created_at' => Carbon::now(),
                    'updated_at' => Carbon::now(),
                ];
            }
            if (!empty($attributes)) {
                GroupMember::query()->insert($attributes);
            }

            DB::commit();
        } catch (\Exception $exception) {
            DB::rollBack();
            // 处理异常
            throw $exception;
        }

        return $group;
    }

    public static function remove(User $user)
    {
        DB::beginTransaction();
        try {
            GroupMember::query()
                ->where([
                    'leader_id' => $user->getAttribute('id'),
                ])->delete();
            $user->update([
                'is_group_leader' => 0,
            ]);
            Group::query()->where([
                'user_id' => $user->getAttribute('id'),
            ])->delete();
            DB::commit();
        } catch (\Exception $exception) {
            DB::rollBack();
            throw $exception;
        }
    }

    public static function findLatestGroup(User $user)
    {
        //推荐人是普通团长
        if ($user->getAttribute('is_group_leader')) {
            $condition = [
                'user_id' => $user->getAttribute('id'),
            ];
            $group = Group::query()->where($condition)->first();
            if ($group) {
                return $group;
            }
        }
        //推荐人是高级团长
        $member = GroupMember::query()
            ->with(['group'])
            ->where([
                'user_id' => $user->getAttribute('id'),
            ])->first();
        if ($member) {
            return $member->group;
        }

        $condition = [];
        if ($user->is_group_leader == 1) {
            $condition = [
                'user_id' => $user->getAttribute('id'),
            ];
        } else {
            $parents = self::getAllAncestors($user);
            foreach ($parents as $parent) {
                if ($parent['is_group_leader'] == 1) {
                    $condition = [
                        'user_id' => $parent['id'],
                    ];
                    break;
                }
            }
        }
        if (!empty($condition)) {
            return Group::query()->where($condition)->first();
        }

        return null;
    }

    public static function addMember(Group $group, User $user)
    {
        $attributes = [
            'user_id' => $user->getAttribute('id'),
        ];

        $member = GroupMember::query()->where($attributes)->first();
        if (!$member) {
            $attributes = array_merge($attributes, [
                'group_id' => $group->getAttribute('id'),
                'leader_id' => $group->getAttribute('user_id'),
                'type' => GroupMemberEnum::TYPE_MEMBER,
                'joined_at' => $user->getAttribute('registered_at'),
            ]);
            $member = GroupMember::query()->create($attributes);
        } else {
            $member->update([
                'joined_at' => $user->getAttribute('registered_at'),
            ]);
        }

        return $member;
    }

    // 获取所有上级直到上级为团长
    protected static function getAllAncestors(User $user)
    {
        $ancestors = collect();
        $parent = User::query()
            ->select(['id', 'parent_id', 'is_group_leader', 'registered_at'])
            ->where([
                'id' => $user->getAttribute('parent_id'),
            ])->first();
        if ($parent) {
            $ancestors->push($parent);
            if (!$parent->is_group_leader) {
                $ancestors = $ancestors->merge(self::getAllAncestors($parent));
            }
        }

        return $ancestors;
    }

    // 获取所有非团长的下级成员
    protected static function getAllDescendants(User $user)
    {
        $descendants = collect();
        $children = User::query()
            ->select(['id', 'parent_id', 'is_group_leader', 'registered_at'])
            ->where([
                'parent_id' => $user->getAttribute('id'),
            ])->get();
        foreach ($children as $child) {
            $descendants->push($child);
            if (!$child->is_group_leader) {
                $descendants = $descendants->merge(self::getAllDescendants($child));
            }
        }

        return $descendants;
    }
}
